package com.bodgittandscarper.broker.client;

import java.rmi.Remote;
import java.rmi.RemoteException;

import suncertify.db.RecordNotFoundException;

import com.bodgittandscarper.broker.types.DatabaseSchema;
import com.bodgittandscarper.broker.types.Record;


/**
 * Interface defining methods that can be invoked remotely by the client. 
 * <p>
 * This <code>BrokerClient</code> acts as a boundary class between the GUI and Server Application. 
 * 
 * @author Morten Rummelhoff
 *
 */
public interface BrokerClient extends Remote {

	/**
	 * Fetches the DatabaseScheme from the Server. The {@link DatabaseSchema} holds information about 
	 * the database structure.  
	 * 
	 * @see DatabaseSchema
	 * @return the <code>DatabaseScheme</code> defined in the database file.
	 * @throws RemoteException if a RMI connection exception occurred 
	 */
	public DatabaseSchema getDatabaseSchema() throws RemoteException;
	
	/**
	 * Searches through all valid records in the database and returns an array of matching records.
	 * It combines the <code>find(String[])</code> and <code>read(int)</code> methods defined in the {@link suncertify.db.Data} class.
	 * 
	 * @param criteria Search criteria for each field in the database. 
	 * Field n in the database file is described by criteria[n]. A null value in criteria[n] 
	 * matches any field value. a non-null value in criteria[n] matches any field value that begins with 
	 * criteria[n].
	 * <p>
	 * @return an array of matching <code>record</code>(s).
	 * @throws RemoteException if a RMI connection exception occurred
	 * @throws RecordNotFoundException If no <code>Record</code>(s) could be found with the given criteria.
	 */
	public Record[] findRecords(String[] criteria) throws RemoteException, RecordNotFoundException;
		
	/**
	 * Locks a <code>Record</code> so that it can only be updated or deleted by this client.
	 * If the <code>Record</code> is already locked, this method will block until the <code>Record</code> 
	 * is unlocked by another client. 
	 * 
	 * @param recNo <code>Record</code> number to be locked
	 * @throws RemoteException if a RMI connection exception occurred
	 * @throws RecordNotFoundException If the specified <code>Record</code> could not be found. 
	 * @see #unlockRecord(int)
	 */
	public void lockRecord(int recNo) throws RemoteException, RecordNotFoundException;
	
	/**
	 * Unlocks a <code>Record</code>. No check is made if the Record was unlocked. When a Record is successfully unlocked
	 * all waiting clients will be notified. 
	 * 
	 * @param recNo <code>Record</code> number to be unlocked
	 * @throws RemoteException if a RMI connection exception occurred
	 * @throws RecordNotFoundException If the specified <code>Record</code> could not be found.
	 * @see #lockRecord(int)
	 */
	public void unlockRecord(int recNo) throws RemoteException, RecordNotFoundException;
	
	/**
	 * Modifies the fields of a record. The new value for the field n appears in recordData[n]
	 * 
	 * @param recNo Record number to be updated
	 * @param recordData An Array of recordData to be updated. The length of recordData shall match exactly
	 * the number of fields in the database. 
	 * @throws RemoteException if a RMI connection exception occurred
	 * @throws RecordNotFoundException If the specified <code>Record</code> could not be found.
	 */
	public void updateRecord(int recNo, String[] recordData) throws RemoteException, RecordNotFoundException;
}
